package main

import (
	"database/sql"
	"log"
	"os"
	"time"

	"gorm.io/gorm/logger"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Product struct {
	gorm.Model
	//Code  string
	Code  sql.NullString
	Price uint
}

func main() {
	dsn := "root:root@tcp(192.168.1.11:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"

	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second, // Slow SQL threshold
			LogLevel:                  logger.Info, // Log level
			IgnoreRecordNotFoundError: true,        // Ignore ErrRecordNotFound error for logger
			Colorful:                  true,        // Disable color
		},
	)

	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger: newLogger,
	})
	if err != nil {
		panic(err)
	}
	// 迁移 schema
	db.AutoMigrate(&Product{})

	// Create
	db.Create(&Product{Code: sql.NullString{"D42", true}, Price: 100})

	// Read
	var product Product
	//SELECT * FROM `products` WHERE `products`.`id` = 1 AND `products`.`deleted_at` IS NULL ORDER BY `products`.`id` LIMIT 1
	db.First(&product, 1) // 根据整形主键查找
	//SELECT * FROM `products` WHERE code = 'D42' AND `products`.`deleted_at` IS NULL AND `products`.`id` = 1 ORDER BY `products`.`id` LIMIT 1
	db.First(&product, "code = ?", "D42") // 查找 code 字段值为 D42 的记录

	// Update - 将 product 的 price 更新为 200
	//UPDATE `products` SET `price`=200,`updated_at`='2021-06-27 19:37:53.754'
	db.Model(&product).Update("Price", 200)

	// Update - 更新多个字段
	//UPDATE `products` SET `updated_at`='2021-06-27 19:37:53.836',`code`='F42',`price`=200
	db.Model(&product).Updates(Product{Price: 200, Code: sql.NullString{"D42", true}}) // 仅更新非零值字段

	//UPDATE `products` SET `updated_at`='2021-06-27 19:52:07.858',`code`='',`price`=200
	db.Model(&product).Updates(Product{Price: 200, Code: sql.NullString{"", true}}) //更新零值

	//UPDATE `products` SET `code`='F42',`price`=200,`updated_at`='2021-06-27 19:37:53.837'
	db.Model(&product).Updates(map[string]interface{}{"Price": 200, "Code": "F42"})

	// Delete - 删除 product
	//UPDATE `products` SET `deleted_at`='2021-06-27 19:42:08.527' WHERE `products`.`id` = 1 AND `products`.`deleted_at` IS NULL
	db.Delete(&product, 1)
}
